/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

package opensocial.apps.friendforsale.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import opensocial.apps.common.persistence.DAOService;
import opensocial.apps.friendforsale.model.Activity;
import opensocial.apps.friendforsale.model.ActivityType;
import opensocial.apps.friendforsale.model.Player;
import opensocial.apps.friendforsale.model.PlayerPK;

public class FriendDAOPersist implements FriendPersist {
  private DAOService<Player> playerService;
  private DAOService<Activity> activityService;

  private static FriendDAOPersist instance;

  public static FriendDAOPersist getInstance() {
    if (instance == null) {
      instance = new FriendDAOPersist();
    }
    return instance;
  }

  private FriendDAOPersist() {
    playerService = new DAOService<Player>(Player.class);
    activityService = new DAOService<Activity>(Activity.class);
  }

  public Player load(PlayerPK pk) {
    return playerService.find(pk);
  }
  
  public void remove(Player p){
    playerService.remove(p);
  }

  public Player load(String container, String id) {
    return load(new PlayerPK(container, id));
  }

  public void save(Player data) {
    playerService.save(data);
  }

  public List<Activity> loadActivity(PlayerPK pk) {
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("container", pk.getContainer());
    params.put("actor", pk.getUid());
    String sql = "select a from Activity a where a.container = :container and (a.actor = :actor or a.target = :actor)"
        + " order by time";
    return activityService.query(sql, params);
  }

  public void save(Activity ai) {

    activityService.save(ai);
  }

  public Activity getLastActivity(Player viewer, Player target,
      ActivityType type) {
    Map<String, Object> params = new HashMap<String, Object>();
    if (viewer == null || target == null) {
      return null;
    }
    params.put("type", type);
    String sql = "select a from Activity a where a.container = :container and a.type = :type";

    if (viewer != null) {
      params.put("viewer", viewer.getUserId());
      params.put("container", viewer.getContainer());
      sql += " and a.actor = :viewer";
    }
    if (target != null) {
      params.put("target", target.getUserId());
      params.put("container", target.getContainer());
      sql += " and a.target = :target";
    }
    sql += " order by a.time";

    return activityService.queryFirst(sql, params);
  }

  public List<Activity> loadActivity(Player player) {
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("container", player.getContainer());
    params.put("actor", player.getUserId());
    String sql = "select a from Activity a where a.container = :container and (a.actor = :actor or a.target = :actor) order by a.time desc";

    return activityService.query(sql, params, 0, 10);
  }

  public List<Player> loadSlaves(Player player) {
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("container", player.getContainer());
    params.put("masterid", player.getUserId());
    String query = "select p from Player p where p.container = :container and p.masterid = :masterid";

    return playerService.query(query, params);
  }

  public List<Player> loadFriends(String container, String ids) {
    String query = "select p from Player p where p.container = :container";
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("container", container);
    if (ids != null) {
      query += " and p.uid in (" + ids + ")";
    }

    return playerService.query(query, params);
  }

  public List<Player> top(String container, String in, String sort, int max) {
    String query = "select p from Player p where p.container = :container";
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("container", container);
    if (in != null) {
      query += " and p.uid in (" + in + ")";
    }
    if (sort != null) {
      query += " order by p." + sort;
    }

    return playerService.query(query, params, 0, max);
  }

  public void remove(Activity activity) {
    activityService.remove(activity);
  }

}
